package apis

import (
	"crypto/md5"
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/go-admin-team/go-admin-core/sdk/api"
	"github.com/go-admin-team/go-admin-core/sdk/config"
	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
	"io/ioutil"
	"net/http"
	"net/url"
	"strings"
	"sync"
	"time"
	"tuowei.com/app/api/service"
	"tuowei.com/pkg/xlog"
)

var key = "hypZmQLB4862"                              //客户授权key
var customer = "B97DF66EFF87153197386CA98A17EF98"     //查询公司编号
var url1 = "https://poll.kuaidi100.com/poll/query.do" //请求地址

type SysKuaiDi struct {
	api.Api
}

var ComName sync.Map

func init() {
	ComName.Store("shentong", "申通快递")
	ComName.Store("zhongtong", "中通快递")
	ComName.Store("shunfeng", "顺丰速运")
	ComName.Store("debangkuaidi", "德邦快递")
	ComName.Store("jtexpress", "极兔速递")
	ComName.Store("jd", "京东物流")
	ComName.Store("ems", "EMS")
	ComName.Store("yuantong", "圆通速递")
	ComName.Store("yunda", "韵达快递")
	ComName.Store("tiantian", "天天快递")
}
func (e SysKuaiDi) PollQuery(c *gin.Context) {
	s := service.SysScore{}
	req := SysPollQueryReq{}
	err := e.MakeContext(c).
		MakeOrm().
		Bind(&req).
		MakeService(&s.Service).
		Errors
	if err != nil {
		e.Logger.Error(err)
		e.Error(500, err, err.Error())
		return
	}
	if req.BuyerId == 0 {
		req.BuyerId = user.GetUserId(c)
	}
	//物流信息缓存到redis，请控制每一单查询频率至少在半小时以上，否则会造成锁单
	p, err := config.GetRedisClient().Get(req.ExpressCompany + ":" + req.ExpressNumber).Bytes()
	if err != nil {
		xlog.Errorf("redis get key:%s,err:%v", req.ExpressCompany+":"+req.ExpressNumber, err)
		p := pollQuery(req.ExpressCompany, req.ExpressNumber)
		e.OK(p, "查询成功")
	} else {
		rd := respDate{}
		err := json.Unmarshal(p, &rd)
		if err != nil {
			xlog.Errorf("redis redis get key:%s,err:%v", req.ExpressCompany+":"+req.ExpressNumber, err)
			//rd = pollQuery(req.ExpressCompany, req.ExpressNumber)
		}
		e.OK(rd, "查询成功")
	}

}

type SysPollQueryReq struct {
	BuyerId        int    `json:"buyer_id"`
	ExpressCompany string `json:"express_company"`
	ExpressNumber  string `json:"express_number"`
}

type PollQuery struct {
	Com string `json:"com"`
	Num string `json:"num"`
	//Phone string `json:"phone"`
	//From string `json:"from"`
	//To string `json:"to"`
	//Resultv2 string `json:"resultv2"`
	//Show string `json:"show"`
	//Order string `json:"order"`
}

func pollQuery(com, num string) respDate {
	rd := respDate{}
	p := PollQuery{
		Com: com,
		Num: num,
	}
	param, err := json.Marshal(p)
	if err != nil {
		xlog.Error("PollQueryReq err:", err)
		return rd
	}
	paramStr := string(param)
	tempSign := paramStr + key + customer
	//md5 加密
	newSig := md5.Sum([]byte(tempSign)) //转成加密编码
	// 将编码转换为字符串
	newArr := fmt.Sprintf("%x", newSig)
	//输出字符串字母都是小写，转换为大写
	sign := strings.ToTitle(newArr)

	contentTypes := "application/x-www-form-urlencoded"
	Request := make(map[string]string, 0)
	Request["customer"] = customer
	Request["param"] = paramStr
	Request["sign"] = sign
	DataUrlVal := url.Values{}
	for k, v := range Request {
		DataUrlVal.Add(k, v)
	}
	resp, err := http.Post(url1, contentTypes, strings.NewReader(DataUrlVal.Encode()))
	if err != nil {
		xlog.Errorf("post failed, err:%v\n", err)
		return rd
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		xlog.Errorf("Body ReadAll, err:%v\n", err)
		return rd
	}
	xlog.Info("body ReadAll:", string(body))
	err = json.Unmarshal(body, &rd)
	if err != nil {
		xlog.Errorf("Body Unmarshal, err:%v\n", err)
		return rd
	}
	comName1, ok := ComName.Load(rd.Com)
	if ok {
		rd.ComName = comName1.(string)
	}
	if rd.Status != "200" {
		xlog.Errorf("kuaidi respDate:%+v", rd)
		return rd
	}
	rdb, err := json.Marshal(rd)
	if err != nil {
		xlog.Errorf("Marshal key:%s,err:%v", com+":"+num, err)
		return rd
	}
	//物流信息缓存到redis，请控制每一单查询频率至少在半小时以上，否则会造成锁单
	err = config.GetRedisClient().Set(com+":"+num, rdb, time.Minute*31).Err()
	if err != nil {
		xlog.Errorf("redis get key:%s,err:%v", com+":"+num, err)
	}
	return rd
}

type respDate struct {
	Message   string      `json:"message"`
	Nu        string      `json:"nu"`
	Ischeck   string      `json:"ischeck"`
	Condition string      `json:"condition"`
	Com       string      `json:"com"`
	ComName   string      `json:"com_name"`
	Status    string      `json:"status"`
	State     string      `json:"state"`
	Data      interface{} `json:"data"`
}
